// Copyright 2011 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * Process the work in the flame.internal.resolveWork array until it is empty,
 * throwing an error if a non-existent action is encountered.
 */
flame.internal.processResolveWork = function() {
  var fi = flame.internal;

  // Walk through the list of resolve work repeatedly until we either empty it
  // out or make it entirely through the list without making any progress.
  var packagesProcessed = new fi.StringSet;

  while (fi.resolveWork.length != 0) {
    var madeProgress = false;
    for (var i = 0; i < fi.resolveWork.length; ++i) {
      // Process the ith element.
      var workItem = fi.resolveWork[i];

      var result =
          fi.processResolveWorkItem(
              workItem,
              fi.registeredActions,
              packagesProcessed,
              fi.processFlameFile);

      // Keep track of whether we made any progress with this item.
      madeProgress = madeProgress || result[1];

      // Was this item completed successfully?
      if (result[0]) {
        fi.resolveWork.splice(i, 1);
        --i;
      }
    }

    // If we didn't make any progress in this run and the array is not empty,
    // the first item must contain non-existent actions.
    if (madeProgress || fi.resolveWork.length == 0) continue;

    function actionDoesntExist(name) {
      return !fi.registeredActions.contains(name);
    }

    var nonexistentActions =
        fi.resolveWork[0].actionNames.filter(actionDoesntExist);
    throw new Error('Unknown action: ' + nonexistentActions[0]);
  }
};
